﻿using System;
using ALApps.Graphics.Interface.Engine;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace ALApps.Graphics.Interface.Items
{
    #region delegates
    public delegate void IndexChangedEventHandler(object sender, IndexChangedEventArgs e);
    #endregion

    /// <summary>
    /// A ALApp.Graphics.Interface Slider item used for easily changing values.
    /// </summary>
    public class Slider : TextureBlock, IDrawableItem
    {
        #region fields
        private Allignment allignment; //Used to evaluate the allignment of the slider.
        private bool dragging; //Is the mouse dragging the indexer?
        private int index; //The sliders index.
        private float indexPerPixelRatio; //The index per pixel ratio.
        #endregion

        #region properties
        /// <summary>
        /// The Width / Height of the sliderButton based on allignment.
        /// </summary>
        public int ButtonSize { get; set; }

        /// <summary>
        /// The slider buttons color.
        /// </summary>
        public Color ButtonColor { get; set; }

        /// <summary>
        /// The slider buttons texture.
        /// </summary>
        public Texture2D ButtonTexture { get; set; }

        public int Index { get { return index; } }

        public int IndexRange { get; set; }

        public string Allignment
        {
            get { return allignment.ToString(); }
            set
            {
                allignment = (Allignment)Enum.Parse(typeof(Allignment), value);
            }
        }
        #endregion

        #region initialization
        public Slider()
        {
            ButtonColor = Color.White;
            IndexChanged = new IndexChangedEventHandler((s, e) => { });
        }

        public override void Initialize()
        {
            base.Initialize();

            string button = string.Format(@"
<root>
    <import assembly=|ALApps.InterfaceEditor| mode=|Name| as=|IE| />
    <using namespace=|ALApps.InterfaceEditor.Interface.Items| as=|AIII| />
    <item>
        <_IE.AIII.Button Name=|button| Width=|{0}| Height=|{1}| Color=|Color.White| />
    </item>
</root>
".Replace('|', '"'), allignment == Items.Allignment.Horizontal ? ButtonSize : Width,
 allignment == Items.Allignment.Vertical ? ButtonSize : Height);

            indexPerPixelRatio = (float)IndexRange / (float)((allignment == Items.Allignment.Horizontal ? Width : Height) - ButtonSize);

            TextureBlock b = (TextureBlock)InterfaceEngine.CompileXmlItem(button);
            b.Color = ButtonColor;
            b.Texture = ButtonTexture ?? InterfaceEngine.Scripting.Execute("Textures['prim']");
            b.OnMouseLeftClicked += (s, e) => { dragging = true; };
            b.OnMouseLeftReleased += (s, e) => { dragging = false; };
            b.OnLostFocus += (s, e) => { dragging = false; };
            AddChild(b);
        }
        #endregion

        #region methods
        public override void Update()
        {
            int lastIndex = index;

            base.Update();

            if (dragging)
            {
                if (allignment == Items.Allignment.Horizontal)
                    Childs["button"].X += (int)InterfaceEngine.Input.MouseDelta.X;
                else
                    Childs["button"].Y += (int)InterfaceEngine.Input.MouseDelta.Y;

                if (allignment == Items.Allignment.Horizontal)
                {
                    if (Childs["button"].X < 0) 
                        Childs["button"].X = 0;
                    else if (Childs["button"].X + Childs["button"].Width > Width)
                        Childs["button"].X = Width - Childs["button"].Width;
                }
                else
                {
                    if (Childs["button"].Y < 0)
                        Childs["button"].Y = 0;
                    else if (Childs["button"].Y + Childs["button"].Height > Height)
                        Childs["button"].Y = Height - Childs["button"].Height;
                }

                index = (int)(indexPerPixelRatio * (allignment == Items.Allignment.Horizontal ? Childs["button"].X : Childs["button"].Y));
                if(lastIndex != index)
                    IndexChanged(this, new IndexChangedEventArgs(allignment == Items.Allignment.Horizontal ? index : IndexRange - index));
            }
        }
        #endregion

        #region events
        public event IndexChangedEventHandler IndexChanged;
        #endregion
    }

    #region eventArgs
    public class IndexChangedEventArgs : EventArgs
    {
        public int NewIndex { get; protected set; }

        public IndexChangedEventArgs(int index)
        {
            NewIndex = index;
        }
    }
    #endregion
}